Types are the foundation of all Xconq game designs. Types are like classes in object-oriented programming but simpler; each set of types is fixed and used only in a particular way by Xconq. A game design defines types of units, materials, and terrain. Only materials are optional; every game design must define at least one unit type and one terrain type.
Types in GDL are simple compared to most other languages. There is no inheritance, no subtyping, no coercions or conversions. This is not a real limitation, since game designs are usually too small to make effective use of any sort of inheritance. Also, game design is an exacting activity; inheritance is often difficult to control satisfactorily. You can use lists of types to simulate inheritance as necessary; this is actually more flexible, because you can have any number of lists with any set of types in each. It may not seem as efficient, but GDL is only used during startup, and is almost entirely array- and struct-based during the game. (A few places, such as scorekeeping, examine GDL forms during play.)
Types are defined one at a time in the game module file. Each type gets an index from 0 on up, in order of the type's appearance in the file. Although this is not normally visible to you or to the player, some error messages and other places will make reference to raw type indices. Each category of type - unit, material, and terrain is indexed individually.
Unit types define what the players get to play with. Unit types can include almost anything; people, buildings, airplanes, monsters, arrows, boulders, you name it.
The basic form of a unit type definition is so:
(unit-type type-name (property-name property-value) ...)
The appearance of this form in a file means you are adding a new and
distinct type, which has no relation to any other types defined before
and after this one. The type-name must be a unique symbol,
such as building
or |fire truck|
. (Note that you can set
things up so that players never see the type-name anywhere,
so don't worry if your preferred name conflicts with something else,
just choose another name.)
The property-name and property-value pairs are entirely optional.
They can always be defined or changed later in the file.
There is little advantage one way or another.
This particular syntax - keyword followed by name or other identifier followed by property/value pairs - will be used for most GDL definitions.
The number of unit types is limited. The exact limit depends on the implementation, but is guaranteed to be at least 127. This is a huge number of types in practice; the only situations where this might be needed would be a fantasy-type game with many types of items and monsters. For empire-building games, 8-16 unit types is far more reasonable. Keep in mind that with lots of types, players have more to keep track of, internal data structures will be larger and take longer to work with, and designing the game will take more time and energy. Consider also that Xconq gives you a lot of properties that you can set individually for each unit type, so that when other game systems might require a distinct types, Xconq lets you use the same type with different propertys. For instance, in a fantasy game you wouldn't need to define "young dragons" and "old dragons" as distinct types, instead you can vary the hit points or experience of a generic "dragon" type.
Each cell in the world has a terrain type. This type should be thought of as the predominant contents of the cell, whether it be open ground, forest, city streets, or the vacuum of deep space. The type can be anything you want, and should be adapted to fit the game you're designing. Sure, the real world has swamps, but if you're designing a game set in the Sahara, don't bother defining a swamp terrain type. Also, the type doesn't carry any preconceptions about elevation or climate, so you can have swamps at 20,000 feet just as easily as at sea level.
The limit on the number of terrain types is large (up to about 127, depending on the implementation), but in practice, 6-10 types offer variety without being confusing. Ideally, several of those types will be uncommon in the world, so that map displays will consist mostly of 3-4 types of terrain.
Some game designs involve entities that are very large and do not move around. Such entities could plausibly be represented either as non-moving units or as a distinct terrain type. To make the right choice, you need to consider the special characteristics you want to implement. Terrain cannot (usually) be changed during the game, nor can it be moved, but units can be damaged or belong to different sides. A realistic example of this choice occurs in the monster game - should a destroyed building become a "rubble-pile" unit or should the building stand on rubble-pile terrain and vanish when it is destroyed? Both choices are plausible; if the rubble-pile is a unit, then the original building is then on top of an empty city block, and after the building is destroyed, the rubble-pile unit can itself be cleaned off, exposing the empty city block again. However, you have to decide whether the rubble-pile unit belongs to a side, how it interacts with other units, and so forth. Rubble-pile terrain is simpler, but the players then get descriptions of brand-new buildings sitting in the midst of rubble-piles, which is confusing. This is a case where there is no "right" answer.
Material types are the simplest to define. They have only a few properties of their own; most of the time they just index tables along with the other types. Materials do not act on their own in any way; instead, players manipulate materials as part of doing other actions. For instance, you can specify that movement, combat, and even a unit's very survival depends on having a supply of some material, or that some material is ammo and consumed gradually when fighting.
The use of materials is pretty much up to you. You don't have to define any material types at all, and game designs with materials are usually more complicated. However, the increase in realism is often worth it; with materials you can limit player activity and/or make some actions more "expensive" than others.
As with the other types, you can define up to about 127 material types, but that would be enough to model the entire global economy accurately! (and take all week to compute a single turn...) 1-3 types is reasonable.
The next sections describe the "static" relationships between types of objects, meaning those relations which must always hold, both in the initial setup and throughout a game.
By default, Xconq allows only one unit in each cell at a time. This has the advantage of simplicity, but also makes some bizarre situations, such as the ability of a merchant ship to prevent an airplane from passing overhead or a submarine from passing underneath.
To fix this, you can allow players to stack several units in the
same cell. This is governed by several tables, which give you control
over which and how many of each type can stack together in which kinds
of terrain. The basic idea is that a cell has a certain amount of room
for units, as specified by the terrain type property capacity
,
and each unit has a certain size in the cell, according to the table
unit-size-in-terrain
.
(add (plains canyons) capacity (10 2)) (table unit-size-in-terrain ((indians town) plains (1 5)) ((indians town) canyons (1 2)) )
In this example, a player can fit 10 indians or 2 towns into a plains cell, or else one town and 5 indians, while canyons allow only 2 indians or one town.
In addition, some unit types may be able to count on a terrain type providing
a guaranteed place; for this, you can use the unit/terrain table
terrain-capacity-x
. This table (which defaults to 0) allows
the specified number of units of each type to be in each type of
terrain, irrespective of who else is there. For instance,
a space station could be given space via
(table terrain-capacity-x (space-station t* 10000))
So while units on the ground are piling together and being constrained by capacity, space stations overhead can stack together freely (space is pretty big, after all).
Occupants and transports work similarly to stacking in terrain; there is both a specialized capacity and a generic capacity that units' sizes count against.
(add (transport carrier) capacity (8 4)) (table unit-size-as-occupant ((infantry armor) transport (1 2)) ((fighter bomber) carrier (1 4)) ) (table unit-capacity-x (carrier fighter 4) )
It may be that all the different sizes interact so that you can't
prevent huge numbers of small units being able to occupy a single
transport. To fix this, use occupants-max
.
Transport is a physical relationship, so for instance one cannot use transports to define a convoy whose acp-per-turn is determined by its slowest member. (This doesn't mean you can't define a convoy type, but you will have to pick an arbitrary speed for it.)
Watch out for unexpected side effects of setting the capacity
but not the unit-size-as-occupant
! Since unit-size-as-occupant
defaults to 1, then a unit with a nonzero capacity can by default
take on any other type as an occupant!
Also, don't let units carry others of their own type. Not only is this of doubtful meaning, Xconq is not guaranteed to cope well with this situation, since it allows infinite recursion in the occupant-transport relation. Ditto for loops; "A can carry B which can carry C which can carry A".
It is tempting to try to define independent sets of types, each in a separate module, and glue them together somehow. However, this doesn't work well in practice, because in a game, the types interact in unexpected ways. Suppose, for example, that you define a set of airplane types that you want to be generic enough to use with several different games. The assessment of those types may vary drastically from game to game; in one, airplanes are 100 times faster than any other sort of unit, so that moving airplanes takes up 99% of game play, while in another, the same set of airplane types are too weak to be of any interest to players.
There is a standard set of terrain types called "stdterr"
.
This set has a mix of the types found most useful for "Empire-type" games,
and Earth-like percentages for random world generation.